package ldkxingzhe.ldkxingzhedemo.widgets.treeview;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import ldkxingzhe.ldkxingzhedemo.R;

/**
 * 自定义的TreeView
 * Created by xingzhe on 15/11/20.
 */
public class LDKTreeView extends LinearLayout{

    private final String TAG = LDKTreeView.class.getSimpleName();


    interface OnLastLevelClickListener{
        /**
         * 最后一级被点击
         * @param treeNode    被点击的节点
         */
        void onLastLevelClick(TreeNode treeNode);
    }

    // MAKR: UI Elements
    ListView mListView;
    LinearLayout mLinearLayout;
    HorizontalScrollView mScrollView;
    List<TreeNode> mSelects = new ArrayList<>();
    MyListViewAdapter mListViewAdapter;
    MySpinnerOnItemSelectListener mOnItemSelectListener;
    private TreeNode mCurrentTreeNode = new TreeNode();
    private Context mContext;
    private OnLastLevelClickListener onLastLevelClickListener;
    private GestureDetector mGestureDetector;
    /** 初始化 */
    private void init() {
        LinearLayout layout = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.ldk_tree_view, null);
        mListView = viewById(layout, R.id.list_view);
        mLinearLayout = viewById(layout, R.id.linear_layout);
        mScrollView = viewById(layout, R.id.scroll_view);
        mListViewAdapter = new MyListViewAdapter(mContext);
        mListView.setAdapter(mListViewAdapter);
        mOnItemSelectListener = new MySpinnerOnItemSelectListener();
        addView(layout);
        mGestureDetector = new GestureDetector(mContext, new MyFlingGestureDetector());
    }

    /**
     * 设置rootTreeNode
     * @param rootTreeNode    跟节点
     */
    public void setTreeNode(@NonNull TreeNode rootTreeNode){
        mLinearLayout.removeAllViews();
        mSelects.clear();
        mCurrentTreeNode = rootTreeNode;
        mListViewAdapter.notifyDataSetChanged();
    }

    /**
     * 设置最后一级点击后的监听
     * @param listener    监听
     */
    public void setOnLastLevelClickListener(OnLastLevelClickListener listener){
        this.onLastLevelClickListener = listener;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mGestureDetector.onTouchEvent(ev);
    }

    // 跳转下一级列表项时
    private void onJumpToNextLevel(int position){
        mSelects.add(mCurrentTreeNode);
        addSpinner(position);
        mCurrentTreeNode = mCurrentTreeNode.getTreeNodeAt(position);
        mListViewAdapter.notifyDataSetChanged();
    }

    /**
     * 界面层级返回事件
     * @return ture 返回上一级, false 已经是顶级
     */
    public boolean onBackLevel(){
        boolean result = false;
        if(mSelects.size() > 0){
            mCurrentTreeNode = mSelects.get(mSelects.size() - 1);
            clean(mSelects.size() - 1);
            result = true;
            mListViewAdapter.notifyDataSetChanged();
        }
        return result;
    }
    /**
     * 添加一个Spinner
     * @param position    添加的位置
     * @return            Spinner
     */
    private Spinner addSpinner(final int position) {
        LinearLayout layout = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.text_spinner, null);
        // 设置label
        TextView label = ((TextView) layout.findViewById(R.id.label));
        label.setText(mCurrentTreeNode.getName() + ":");
        label.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v(TAG, "onClick, on label");
                clean(position);
            }
        });

        // 设置spinner
        Spinner spinner = (Spinner)layout.findViewById(R.id.spinner);
        ArrayAdapter arrayAdapter = new ArrayAdapter(mContext, android.R.layout.simple_spinner_item, mCurrentTreeNode.getChildrenNameList());
        spinner.setAdapter(arrayAdapter);
        spinner.setPrompt(mCurrentTreeNode.getName());
        // must added this before setOnItemSelectedListener
        spinner.setSelection(position, false);
        mLinearLayout.addView(layout, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mScrollView.smoothScrollBy(layout.getWidth(), 0);
        spinner.setOnItemSelectedListener(mOnItemSelectListener);
        return spinner;
    }

    /**
     * 命名为clean,
     * 用来将数据层状态复位
     * */
    private void clean(int position) {
        int positionPlus = position + 1;
        while(positionPlus <= mSelects.size()){
            mSelects.remove(position);
            mLinearLayout.removeViewAt(position);
        }
    }
    // 自定义的Adapter
    private class MyListViewAdapter extends BaseAdapter {

        Context mContext;
        Animation animation;
        MyListViewAdapter(Context context){
            this.mContext = context;
            animation = AnimationUtils.loadAnimation(mContext, R.anim.push_left_in);
        }
        @Override
        public int getCount() {
            return mCurrentTreeNode.getChildrenCount();
        }

        @Override
        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
            if(getCount() == 1){
                if(getItem(0) != null){
                    if(onLastLevelClickListener != null){
                        onLastLevelClickListener.onLastLevelClick(getItem(0));
                    }
                    return;
                }
                onJumpToNextLevel(0);
            }
        }

        @Override
        public TreeNode getItem(int position) {
            return mCurrentTreeNode.getTreeNodeAt(position);
        }

        private String getItemName(int position){
            return getItem(position).getName();
        }
        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = LayoutInflater.from(mContext).inflate(android.R.layout.simple_list_item_1,parent,false);
            }
            ((TextView)convertView).setText(getItemName(position));
            convertView.startAnimation(animation);
            convertView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (getItem(position).getObj() != null) {
                        // TODO: 15/11/19
                        Log.v(TAG, "this treeNode is last level");
                        if (onLastLevelClickListener != null) {
                            onLastLevelClickListener.onLastLevelClick(getItem(position));
                        }
                        return;
                    }
                    onJumpToNextLevel(position);
                }
            });
            return convertView;
        }
    }

    private class MySpinnerOnItemSelectListener implements AdapterView.OnItemSelectedListener {
        private final String TAG = MySpinnerOnItemSelectListener.class.getSimpleName();
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            int spinnerPosition = mLinearLayout.indexOfChild((View) parent.getParent());
            mCurrentTreeNode = mSelects.get(spinnerPosition);
            clean(spinnerPosition);
            onJumpToNextLevel(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            Log.v(TAG,"onNothingSelected");
        }
    }
    private class MyFlingGestureDetector extends GestureDetector.SimpleOnGestureListener{

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.v(TAG, "onFling");
            if(e2.getX() - e1.getX() > 20 && velocityX > velocityY ){
                onBackLevel();
                return true;
            }
            return false;
        }
    }
    /** 根据id选择view */
    private<T> T viewById(ViewGroup viewGroup, int id){
        return (T)viewGroup.findViewById(id);
    }
    public LDKTreeView(Context context) {
        this(context, null);
    }

    public LDKTreeView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LDKTreeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
    }
}
